package pab.ui.trans;

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Date;

import java.util.UUID;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.xml.datatype.XMLGregorianCalendar;

import pab.core.account.Account;
import pab.core.exception.AccountException;
import pab.core.exception.TransactionException;
import pab.core.service.AccountService;
import pab.core.service.ExchangeRate;
import pab.core.service.FixedExchangeRate;
import pab.core.transaction.Currency;
import pab.core.transaction.ProjectedInterval;
import pab.core.transaction.Transaction;
import pab.core.transaction.TransactionType;
import pab.ui.GeneralAuxiliary;
import pab.ui.auxiliary.AutoCompleteDecorator;
import pab.ui.auxiliary.datechooser.JDateChooser;
/*
 * Created by JFormDesigner on Thu Jun 09 13:30:20 ICT 2011
 */



/**
 * @author rukowen
 */
public class TransactionAdd extends JDialog {
	/**
	 * 
	 */
 
	private static final long serialVersionUID = 1L;
	private AccountService accountService; 
	String accName;
	ExchangeRate er;
	ArrayList<String> itemsAutoComplete;
	Transaction trans = null;
	public TransactionAdd(Frame owner, String accName, AccountService accountService, Transaction trans) {
		super(owner, true);
		this.accountService = accountService;
		this.accName = accName;
		 er = new FixedExchangeRate();
		initComponents();
		loadInterval();
		if(trans != null){ //update transaction
			this.trans = trans;
			initialUpdateEnvironment();
		}
		txtAmount.setHorizontalAlignment(JTextField.RIGHT);
		txtAmount.addKeyListener(new KeyAdapter()
		   {
		       public void keyTyped (KeyEvent e) 
		        { 
		            char c = e.getKeyChar() ;
		                
		            if (!   ((c==KeyEvent.VK_BACK_SPACE) || (c==KeyEvent.VK_DELETE) 
		                ||  (c== KeyEvent.VK_ENTER)      || (c == KeyEvent.VK_TAB) 
		                ||  (Character.isDigit(c)))) 
		            {
		               e.consume() ;
		           } 
		        } 
		    });
		
		this.setVisible(true);
		
		
	}

	private void initialUpdateEnvironment(){
		this.setTitle("Transaction Update");
		dateTrans.setDate(GeneralAuxiliary.XMLGregorianCalendarToDate(trans.getDate()));
		txtAmount.setText(trans.getAmount()+"");
		cboCurrency.setSelectedItem(trans.getCurrency().getCode());
		rdCredit.setSelected(trans.getType()==TransactionType.CREDIT);
		txtDescription.setText(trans.getDesc());
		if(trans.isProjected()){
			chkProjected.setSelected(true);
			cboInterval.setVisible(chkProjected.isSelected());
			label7.setVisible(chkProjected.isSelected());
			cboInterval.setSelectedItem(intervalToString(trans.getInterval()));
		}
		cboAccount.setEnabled(false);
		chkProjected.setEnabled(false);
		cboInterval.setEnabled(false);
		
	}
	private String intervalToString(ProjectedInterval pro){
		if(pro==ProjectedInterval.MONTH)
			return "Month";
		if(pro == ProjectedInterval.QUARTER)
			return "Quarter";
		if(pro == ProjectedInterval.HALF_YEAR)
			return "6-Month";
		return "Year";
	}
	
	private void loadInterval(){
		cboInterval.addItem("Month");
		cboInterval.addItem("Quarter");
		cboInterval.addItem("6-Month");
		cboInterval.addItem("Year");
	}
	
	
	
	private Account getAccountByName(String accName){
		for(Account c: accountService.listAccounts())
			if(c.getName().equals(accName))
				return c;
		return null;
	}
	
	private void btnOkMouseClicked(MouseEvent e) {
		// TODO add your code here
		if(trans == null){
			try{
				addNewTransaction();
				
				this.dispose();
			}catch(Exception ex){
				JOptionPane.showMessageDialog(this, "Add transaction failed, please check your data");
			}
		}		
		else {//update
			try{
				updateTransaction();
				this.dispose();
			}catch(Exception ex){
				JOptionPane.showMessageDialog(this, "Update transaction failed, please check your data");
			}
			
		}
	}


	
	private void addNewTransaction(){
		//String transNo = UUID.randomUUID().toString();
		Account acc = getAccountByName(cboAccount.getSelectedItem().toString());
		
		TransactionType transType;
		if(rdCredit.isSelected())
			transType = TransactionType.CREDIT;
		else
			transType = TransactionType.DEBIT;
		Double amount  =Double.parseDouble(txtAmount.getText());
		Currency cur = er.getCurrency(cboCurrency.getSelectedItem().toString());
		String descr = txtDescription.getText();
		XMLGregorianCalendar date = GeneralAuxiliary.date2Gregorian(dateTrans.getDate());
		ProjectedInterval interval = GeneralAuxiliary.getIntervalByName(cboInterval.getSelectedItem().toString());
		
		try {
			Transaction retTrans;
			if(chkProjected.isSelected())
				retTrans = accountService.makePriliminaryTransaction(acc, transType, amount, cur, descr, date, interval);
			else
				retTrans = accountService.makePriliminaryTransaction(acc, transType, amount, cur, descr, date);
			
			accountService.save();
			if(chkClear.isSelected())
				accountService.clearTransation(retTrans);
			
			accountService.save();
			this.dispose();
		} catch (TransactionException e1) {
			e1.printStackTrace();
		}
	}
	
	private void updateTransaction(){

		
		trans.setType(rdCredit.isSelected()?TransactionType.CREDIT:TransactionType.DEBIT);
		
		Double amount  = Double.parseDouble(txtAmount.getText());
		trans.setAmount(amount);
		
		Currency cur = er.getCurrency(cboCurrency.getSelectedItem().toString());
		trans.setCurrency(cur);
		
		String descr = txtDescription.getText();
		trans.setDesc(descr);
		
		try {
			if(chkClear.isSelected())
				accountService.clearTransation(trans);
		} catch (TransactionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		accountService.save();
	}
	private void cboAccountItemStateChanged(ItemEvent e) {
		// TODO add your code here
		Account c = getAccountByName(cboAccount.getSelectedItem().toString());
		if (c!=null)
			lblAccountNo.setText(c.getNumber());
	}

	private void chkProjectedStateChanged(ChangeEvent e) {
		// TODO add your code here
		/*if (trans != null){//update
			if(trans.isProjected() && !chkProjected.isSelected()){ //projected -> non projected
				if(!trans.isLatest()){
					JOptionPane.showMessageDialog(this, "Cannot deprojected this transaction, because it's not a latest transaction");
					chkProjected.setSelected(true);
				}	
			}else if(!trans.isProjected() && chkProjected.isSelected()){ //non projected -> projected
				
			}
		}
		else{//la add new{
*/			cboInterval.setVisible(chkProjected.isSelected());
			label7.setVisible(chkProjected.isSelected());
		//}
	}

	private int numMonth(){
		String inteval = cboInterval.getSelectedItem().toString();
		if (inteval.equals("Month"))
			return 1;
		if (inteval.equals("Quarter"))
			return 3;
		if (inteval.equals("6-Month"))
			return 6;
		return 12;
	}
	private void initComponents() {
		itemsAutoComplete = new ArrayList<String>();  


		// JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
		label1 = new JLabel();
		cboAccount = new JComboBox();
		lblAccountNo = new JLabel();
		label3 = new JLabel();
		label4 = new JLabel();
		cboCurrency = new JComboBox();
		label5 = new JLabel();
		rdCredit = new JRadioButton();
		rdDebit = new JRadioButton();
		btnOk = new JButton();
		label6 = new JLabel();
		txtAmount = new JFormattedTextField();
		txtDescription = new JTextField();
		dateTrans = new JDateChooser();
		chkProjected = new JCheckBox();
		label2 = new JLabel();
		cboInterval = new JComboBox();
		label7 = new JLabel();
		chkClear = new JCheckBox();
		label8 = new JLabel();

		//======== this ========
		setTitle("Transaction Add");
		Container contentPane = getContentPane();
		contentPane.setLayout(null);

		//---- label1 ----
		label1.setText("Account");
		contentPane.add(label1);
		label1.setBounds(30, 30, 60, label1.getPreferredSize().height);

		//---- cboAccount ----
		cboAccount.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				cboAccountItemStateChanged(e);
			}
		});
		contentPane.add(cboAccount);
		cboAccount.setBounds(130, 20, 160, 26);

		//---- lblAccountNo ----
		lblAccountNo.setText("[]");
		contentPane.add(lblAccountNo);
		lblAccountNo.setBounds(305, 30, 165, 16);

		//---- label3 ----
		label3.setText("Date");
		contentPane.add(label3);
		label3.setBounds(30, 61, 43, 16);

		//---- label4 ----
		label4.setText("Amount");
		contentPane.add(label4);
		label4.setBounds(30, 92, 85, 16);
		contentPane.add(cboCurrency);
		cboCurrency.setBounds(300, 85, 110, 26);

		//---- label5 ----
		label5.setText("Trans type");
		contentPane.add(label5);
		label5.setBounds(30, 123, 90, 16);

		//---- rdCredit ----
		rdCredit.setText("Credit");
		rdCredit.setSelected(true);
		contentPane.add(rdCredit);
		rdCredit.setBounds(new Rectangle(new Point(135, 121), rdCredit.getPreferredSize()));

		//---- rdDebit ----
		rdDebit.setText("Debit");
		contentPane.add(rdDebit);
		rdDebit.setBounds(220, 121, 55, 18);

		//---- btnOk ----
		btnOk.setText("Ok");
		btnOk.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				btnOkMouseClicked(e);
			}
		});
		contentPane.add(btnOk);
		btnOk.setBounds(130, 270, 85, 28);

		//---- label6 ----
		label6.setText("Description");
		contentPane.add(label6);
		label6.setBounds(30, 185, 90, 16);
		contentPane.add(txtAmount);
		txtAmount.setBounds(130, 85, 165, txtAmount.getPreferredSize().height);
		contentPane.add(txtDescription);
		txtDescription.setBounds(130, 180, 280, 55);

		//---- dateTrans ----
		dateTrans.setBorder(LineBorder.createBlackLineBorder());
		contentPane.add(dateTrans);
		dateTrans.setBounds(130, 52, 160, 25);

		//---- chkProjected ----
		chkProjected.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				chkProjectedStateChanged(e);
			}
		});
		contentPane.add(chkProjected);
		chkProjected.setBounds(new Rectangle(new Point(135, 150), chkProjected.getPreferredSize()));

		//---- label2 ----
		label2.setText("Projected");
		contentPane.add(label2);
		label2.setBounds(new Rectangle(new Point(30, 150), label2.getPreferredSize()));
		contentPane.add(cboInterval);
		cboInterval.setBounds(300, 145, 110, cboInterval.getPreferredSize().height);

		//---- label7 ----
		label7.setText("Interval");
		contentPane.add(label7);
		label7.setBounds(new Rectangle(new Point(220, 150), label7.getPreferredSize()));
		contentPane.add(chkClear);
		chkClear.setBounds(new Rectangle(new Point(135, 240), chkClear.getPreferredSize()));

		//---- label8 ----
		label8.setText("Clear");
		contentPane.add(label8);
		label8.setBounds(new Rectangle(new Point(30, 240), label8.getPreferredSize()));

		contentPane.setPreferredSize(new Dimension(455, 355));
		pack();
		setLocationRelativeTo(getOwner());

		//---- rdButtonGroup ----
		ButtonGroup rdButtonGroup = new ButtonGroup();
		rdButtonGroup.add(rdCredit);
		rdButtonGroup.add(rdDebit);
		// JFormDesigner - End of component initialization  //GEN-END:initComponents
		
		
		cboInterval.setVisible(false);
		label7.setVisible(false);
		loadAccount();
		GeneralAuxiliary.loadCurrency(cboCurrency);
		setAddNewEnvironment();
		loadAutoComplete();
	}


	// JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
	private JLabel label1;
	private JComboBox cboAccount;
	private JLabel lblAccountNo;
	private JLabel label3;
	private JLabel label4;
	private JComboBox cboCurrency;
	private JLabel label5;
	private JRadioButton rdCredit;
	private JRadioButton rdDebit;
	private JButton btnOk;
	private JLabel label6;
	private JFormattedTextField txtAmount;
	private JTextField txtDescription;
	private JDateChooser dateTrans;
	private JCheckBox chkProjected;
	private JLabel label2;
	private JComboBox cboInterval;
	private JLabel label7;
	private JCheckBox chkClear;
	private JLabel label8;
	// JFormDesigner - End of variables declaration  //GEN-END:variables
	
	private void loadAutoComplete(){
		
		
	}
	
	private void setAddNewEnvironment(){
		dateTrans.setDate(new Date());
	}
	
	private void loadAccount(){
		cboAccount.removeAll();
		for(Account a: accountService.listAccounts()){
			cboAccount.addItem(a.getName());
		}
		
		cboAccount.setSelectedItem(accName);
		Account c = getAccountByName(cboAccount.getSelectedItem().toString());
		if (c!=null){
			lblAccountNo.setText(c.getNumber());
			itemsAutoComplete.clear();
			try {
				for(Transaction t:accountService.listTransactions()){
					if(!itemsAutoComplete.contains(t.getDesc()))
						itemsAutoComplete.add(t.getDesc());
				}
			} catch (AccountException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			  
			AutoCompleteDecorator.decorate(txtDescription, itemsAutoComplete, false); 
		}
			
	}
}
